#pragma once
#include <cstring>
#include <cerrno>
#include <string>
#include <iostream>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
namespace yui
{
    // 端口号默认值
    const uint16_t default_port = 8888;
    class UdpServer
    {
    public:
        // UdpServer(const std::string ip, const uint16_t port = default_port)
        //     : port_(port), ip_(ip)
        // {
        // }
        UdpServer( const uint16_t port = default_port)
        : port_(port)
        {}
        ~UdpServer()
        {
        }
        // 初始化服务器
        void Initserver()
        {
            sock_ = socket(AF_INET, SOCK_DGRAM, 0);
            if (sock_ == -1)
            {
                perror("创建套接字失败");
                exit(1);
            }
            std::cout << "创建成功,套接字为：" << sock_ << std::endl;
            // 绑定ip地址和端口号
            struct sockaddr_in local;
            bzero(&local, sizeof(local));
            // 填充字段
            local.sin_family = AF_INET;
            local.sin_port = htons(port_);
            // local.sin_addr.s_addr = inet_addr(ip_.c_str());
            local.sin_addr.s_addr = INADDR_ANY;

            // 绑定IP地址和端口号
            if (bind(sock_, (const sockaddr *)&local, sizeof(local)))
            {
                perror("绑定失败");
                exit(1);
            }
            std::cout << "绑定成功！" << std::endl;
        }
        // 启动服务器
        void StartServer()
        {
            char buf[4096];
            while(true)
            {
                struct sockaddr_in peer;
                socklen_t len = sizeof(peer);

                ssize_t n = recvfrom(sock_,buf,sizeof(buf)-1,0,(struct sockaddr*)&peer,&len);
                if(n > 0)
                {
                    buf[n] = '\0';
                }
                else
                {
                    continue;
                }
                std::string clientIp = inet_ntoa(peer.sin_addr);
                uint16_t clientPort = ntohs(peer.sin_port);
                printf("服务器得到消息[%s:%d]$%s\n",clientIp.c_str(),clientPort,buf);
                //回响给客户端
                //...
            }
        }

    private:
        int sock_;
        uint16_t port_;
        // std::string ip_;
    };
}